package org.cybzacg.encryption.config;

import org.cybzacg.encryption.enums.EncryptionAlgorithm;
import org.cybzacg.encryption.enums.EncryptionType;
import org.cybzacg.encryption.enums.SecurityStrategyEnum;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 加密配置加载器
 * 支持从不同来源加载加密配置
 * 
 * @author encryption team
 * @version 1.0
 */
public class EncryptionConfigLoader {
    
    // 配置缓存
    private static final Map<String, EncryptionConfig> configCache = new ConcurrentHashMap<>();
    
    // 默认配置文件路径
    private static final String DEFAULT_CONFIG_PATH = "encryption-default.properties";
    private static final String DEV_CONFIG_PATH = "encryption-dev.properties";
    private static final String PROD_CONFIG_PATH = "encryption-prod.properties";
    
    /**
     * 从默认配置文件加载配置
     * 
     * @return 加密配置
     */
    public static EncryptionConfig loadDefaultConfig() {
        return loadFromClasspath(DEFAULT_CONFIG_PATH);
    }
    
    /**
     * 从开发环境配置文件加载配置
     * 
     * @return 加密配置
     */
    public static EncryptionConfig loadDevConfig() {
        return loadFromClasspath(DEV_CONFIG_PATH);
    }
    
    /**
     * 从生产环境配置文件加载配置
     * 
     * @return 加密配置
     */
    public static EncryptionConfig loadProdConfig() {
        return loadFromClasspath(PROD_CONFIG_PATH);
    }
    
    /**
     * 从类路径加载配置文件
     * 
     * @param configPath 配置文件路径
     * @return 加密配置
     */
    public static EncryptionConfig loadFromClasspath(String configPath) {
        if (configCache.containsKey(configPath)) {
            return configCache.get(configPath);
        }
        
        try (InputStream inputStream = EncryptionConfigLoader.class.getClassLoader()
                .getResourceAsStream(configPath)) {
            
            if (inputStream == null) {
                throw new IllegalArgumentException("Config file not found: " + configPath);
            }
            
            Properties properties = new Properties();
            properties.load(inputStream);
            
            EncryptionConfig config = createConfigFromProperties(properties);
            configCache.put(configPath, config);
            
            return config;
            
        } catch (IOException e) {
            throw new RuntimeException("Failed to load config from: " + configPath, e);
        }
    }
    
    /**
     * 从Properties对象创建配置
     * 
     * @param properties 属性对象
     * @return 加密配置
     */
    public static EncryptionConfig createConfigFromProperties(Properties properties) {
        EncryptionConfig.Builder builder = new EncryptionConfig.Builder();
        
        // 加密类型配置
        String encryptionType = properties.getProperty("encryption.type", "SYMMETRIC");
        builder.encryptionType(EncryptionType.fromName(encryptionType));
        
        // 加密算法配置
        String defaultAlgorithm = properties.getProperty("encryption.algorithm", "AES");
        builder.algorithm(EncryptionAlgorithm.fromName(defaultAlgorithm));
        
        // 安全策略配置
        String securityStrategy = properties.getProperty("encryption.strategy", "SAFE");
        builder.securityStrategy(SecurityStrategyEnum.fromName(securityStrategy));
        
        // 密钥配置
        String defaultKeySize = properties.getProperty("encryption.keySize", "256");
        builder.keySize(Integer.parseInt(defaultKeySize));
        
        // 转换配置
        String transformation = properties.getProperty("encryption.transformation");
        if (transformation != null) {
            builder.transformation(transformation);
        }
        
        // 提供者配置
        String provider = properties.getProperty("encryption.provider");
        if (provider != null) {
            builder.provider(provider);
        }
        
        // 缓存配置
        boolean cacheEnabled = Boolean.parseBoolean(
            properties.getProperty("encryption.cache.enabled", "true"));
        builder.cacheEnabled(cacheEnabled);
        
        if (cacheEnabled) {
            long cacheExpiration = Long.parseLong(
                properties.getProperty("encryption.cache.expiration", "300000")); // 5分钟
            builder.cacheExpiration(cacheExpiration);
            
            int maxCacheSize = Integer.parseInt(
                properties.getProperty("encryption.cache.maxSize", "1000"));
            builder.maxCacheSize(maxCacheSize);
        }
        
        // 性能监控配置
        boolean monitoringEnabled = Boolean.parseBoolean(
            properties.getProperty("encryption.monitoring.enabled", "true"));
        builder.monitoringEnabled(monitoringEnabled);
        
        // 超时配置
        long timeout = Long.parseLong(
            properties.getProperty("encryption.timeout", "15000")); // 15秒
        builder.timeout(timeout);
        
        // 重试配置
        int maxRetries = Integer.parseInt(
            properties.getProperty("encryption.maxRetries", "3"));
        builder.maxRetries(maxRetries);
        
        long retryInterval = Long.parseLong(
            properties.getProperty("encryption.retryInterval", "1000")); // 1秒
        builder.retryInterval(retryInterval);
        
        // 批处理配置
        boolean batchMode = Boolean.parseBoolean(
            properties.getProperty("encryption.batch.enabled", "false"));
        builder.batchMode(batchMode);
        
        if (batchMode) {
            int batchSize = Integer.parseInt(
                properties.getProperty("encryption.batch.size", "100"));
            builder.batchSize(batchSize);
        }
        
        // 自定义属性
        for (String key : properties.stringPropertyNames()) {
            if (key.startsWith("encryption.custom.")) {
                String value = properties.getProperty(key);
                String customKey = key.substring("encryption.custom.".length());
                builder.additionalProperty(customKey, value);
            }
        }
        
        return builder.build();
    }
    
    /**
     * 从环境变量加载配置
     * 
     * @return 加密配置
     */
    public static EncryptionConfig loadFromEnvironment() {
        EncryptionConfig.Builder builder = new EncryptionConfig.Builder();
        
        // 从环境变量读取配置
        String algorithm = System.getenv("ENCRYPTION_DEFAULT_ALGORITHM");
        if (algorithm != null) {
            builder.algorithm(EncryptionAlgorithm.fromName(algorithm));
        }
        
        String keySize = System.getenv("ENCRYPTION_DEFAULT_KEY_SIZE");
        if (keySize != null) {
            builder.keySize(Integer.parseInt(keySize));
        }
        
        String cacheEnabled = System.getenv("ENCRYPTION_CACHE_ENABLED");
        if (cacheEnabled != null) {
            builder.cacheEnabled(Boolean.parseBoolean(cacheEnabled));
        }
        
        String monitoringEnabled = System.getenv("ENCRYPTION_MONITORING_ENABLED");
        if (monitoringEnabled != null) {
            builder.monitoringEnabled(Boolean.parseBoolean(monitoringEnabled));
        }
        
        // 更多环境变量配置...
        
        return builder.build();
    }
    
    /**
     * 从系统属性加载配置
     * 
     * @return 加密配置
     */
    public static EncryptionConfig loadFromSystemProperties() {
        EncryptionConfig.Builder builder = new EncryptionConfig.Builder();
        
        // 从系统属性读取配置
        String algorithm = System.getProperty("encryption.default.algorithm");
        if (algorithm != null) {
            builder.algorithm(EncryptionAlgorithm.fromName(algorithm));
        }
        
        String keySize = System.getProperty("encryption.default.keySize");
        if (keySize != null) {
            builder.keySize(Integer.parseInt(keySize));
        }
        
        String cacheEnabled = System.getProperty("encryption.cache.enabled");
        if (cacheEnabled != null) {
            builder.cacheEnabled(Boolean.parseBoolean(cacheEnabled));
        }
        
        String monitoringEnabled = System.getProperty("encryption.monitoring.enabled");
        if (monitoringEnabled != null) {
            builder.monitoringEnabled(Boolean.parseBoolean(monitoringEnabled));
        }
        
        // 更多系统属性配置...
        
        return builder.build();
    }
    
    /**
     * 合并多个配置
     * 
     * @param configs 配置数组
     * @return 合并后的配置
     */
    public static EncryptionConfig mergeConfigs(EncryptionConfig... configs) {
        if (configs == null || configs.length == 0) {
            return new EncryptionConfig.Builder().build();
        }
        
        EncryptionConfig.Builder builder = new EncryptionConfig.Builder();
        
        // 按优先级合并配置（后面的配置覆盖前面的）
        for (EncryptionConfig config : configs) {
            if (config != null) {
                mergeConfig(builder, config);
            }
        }
        
        return builder.build();
    }
    
    /**
     * 合并配置到构建器
     */
    private static void mergeConfig(EncryptionConfig.Builder builder, EncryptionConfig config) {
        if (config.getEncryptionType() != null) {
            builder.encryptionType(config.getEncryptionType());
        }
        
        if (config.getAlgorithm() != null) {
            builder.algorithm(config.getAlgorithm());
        }
        
        if (config.getSecurityStrategy() != null) {
            builder.securityStrategy(config.getSecurityStrategy());
        }
        
        if (config.getKeySize() > 0) {
            builder.keySize(config.getKeySize());
        }
        
        if (config.getTransformation() != null) {
            builder.transformation(config.getTransformation());
        }
        
        if (config.getProvider() != null) {
            builder.provider(config.getProvider());
        }
        
        builder.cacheEnabled(config.isCacheEnabled());
        builder.cacheExpiration(config.getCacheExpiration());
        builder.maxCacheSize(config.getMaxCacheSize());
        
        builder.monitoringEnabled(config.isMonitoringEnabled());
        builder.timeout(config.getTimeout());
        builder.maxRetries(config.getMaxRetries());
        builder.retryInterval(config.getRetryInterval());
        
        builder.batchMode(config.isBatchMode());
        builder.batchSize(config.getBatchSize());
        
        // 合并附加属性
        Map<String, Object> additionalProps = config.getAdditionalProperties();
        if (additionalProps != null) {
            for (Map.Entry<String, Object> entry : additionalProps.entrySet()) {
                builder.additionalProperty(entry.getKey(), entry.getValue());
            }
        }
    }
    
    /**
     * 清除配置缓存
     */
    public static void clearCache() {
        configCache.clear();
    }
    
    /**
     * 获取缓存大小
     * 
     * @return 缓存大小
     */
    public static int getCacheSize() {
        return configCache.size();
    }
}
